home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter14 / isohex14_2 / isohex14_2.cpp < prev    next >
C/C++ Source or Header  |  2000-09-27  |  11KB  |  399 lines

  1. /*****************************************************************************
  2. IsoHex14_2.cpp
  3. Ernest S. Pazera
  4. 21JUL2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Requires ddraw.lib and dxguid.lib
  7. Needs DDFuncs.h/cpp, GDICanvas.h/cpp, and TileSet.h/cpp
  8. *****************************************************************************/
  9.  
  10. //////////////////////////////////////////////////////////////////////////////
  11. //INCLUDES
  12. //////////////////////////////////////////////////////////////////////////////
  13. #define WIN32_LEAN_AND_MEAN  
  14.  
  15. #include <windows.h>   
  16. #include "TileSet.h"
  17.  
  18. //////////////////////////////////////////////////////////////////////////////
  19. //DEFINES
  20. //////////////////////////////////////////////////////////////////////////////
  21. //name for our window class
  22. #define WINDOWCLASS "ISOHEX14"
  23. //title of the application
  24. #define WINDOWTITLE "IsoHex 14-2"
  25.  
  26. //map dimensions
  27. const int MAPWIDTH=20;
  28. const int MAPHEIGHT=20;
  29.  
  30. //////////////////////////////////////////////////////////////////////////////
  31. //PROTOTYPES
  32. //////////////////////////////////////////////////////////////////////////////
  33. bool Prog_Init();//game data initalizer
  34. void Prog_Loop();//main game loop
  35. void Prog_Done();//game clean up
  36. POINT DiamondMap_TilePlotter(POINT ptMap,int iTileWidth,int iTileHeight);
  37. void SetUpSpaces();//sets up spaces
  38. void SetUpMap();
  39. void DrawMap();
  40.  
  41. //////////////////////////////////////////////////////////////////////////////
  42. //GLOBALS
  43. //////////////////////////////////////////////////////////////////////////////
  44. HINSTANCE hInstMain=NULL;//main application handle
  45. HWND hWndMain=NULL;//handle to our main window
  46. LPDIRECTDRAW7 lpdd=NULL;//directdraw
  47. LPDIRECTDRAWSURFACE7 lpddsMain=NULL;//primary surface
  48. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;//back buffer
  49. LPDIRECTDRAWCLIPPER lpddClipper=NULL;//clipper
  50. CTileSet tsIso;//tileset
  51. int iTileMap[MAPWIDTH][MAPHEIGHT];
  52.  
  53. //spaces
  54. RECT rcWorldSpace;//worldspace
  55. RECT rcScreenSpace;//screen space(also, view space)
  56. RECT rcAnchorSpace;//anchor space
  57. POINT ptScreenAnchor;//screen anchor
  58.  
  59.  
  60. //////////////////////////////////////////////////////////////////////////////
  61. //WINDOWPROC
  62. //////////////////////////////////////////////////////////////////////////////
  63. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  64. {
  65.     //which message did we get?
  66.     switch(uMsg)
  67.     {
  68.     case WM_KEYDOWN:
  69.         {
  70.             //if escape hit, destroy window
  71.             if(wParam==VK_ESCAPE) DestroyWindow(hWndMain);
  72.             //handled, so return 0
  73.             return(0);
  74.         }break;
  75.     case WM_DESTROY://the window is being destroyed
  76.         {
  77.  
  78.             //tell the application we are quitting
  79.             PostQuitMessage(0);
  80.  
  81.             //handled message, so return 0
  82.             return(0);
  83.  
  84.         }break;
  85.     case WM_PAINT://the window needs repainting
  86.         {
  87.             //a variable needed for painting information
  88.             PAINTSTRUCT ps;
  89.             
  90.             //start painting
  91.             HDC hdc=BeginPaint(hwnd,&ps);
  92.  
  93.             /////////////////////////////
  94.             //painting code would go here
  95.             /////////////////////////////
  96.  
  97.             //end painting
  98.             EndPaint(hwnd,&ps);
  99.                         
  100.             //handled message, so return 0
  101.             return(0);
  102.         }break;
  103.     }
  104.  
  105.     //pass along any other message to default message handler
  106.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  107. }
  108.  
  109.  
  110. //////////////////////////////////////////////////////////////////////////////
  111. //WINMAIN
  112. //////////////////////////////////////////////////////////////////////////////
  113. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  114. {
  115.     //assign instance to global variable
  116.     hInstMain=hInstance;
  117.  
  118.     //create window class
  119.     WNDCLASSEX wcx;
  120.  
  121.     //set the size of the structure
  122.     wcx.cbSize=sizeof(WNDCLASSEX);
  123.  
  124.     //class style
  125.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  126.  
  127.     //window procedure
  128.     wcx.lpfnWndProc=TheWindowProc;
  129.  
  130.     //class extra
  131.     wcx.cbClsExtra=0;
  132.  
  133.     //window extra
  134.     wcx.cbWndExtra=0;
  135.  
  136.     //application handle
  137.     wcx.hInstance=hInstMain;
  138.  
  139.     //icon
  140.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  141.  
  142.     //cursor
  143.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  144.  
  145.     //background color
  146.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  147.  
  148.     //menu
  149.     wcx.lpszMenuName=NULL;
  150.  
  151.     //class name
  152.     wcx.lpszClassName=WINDOWCLASS;
  153.  
  154.     //small icon
  155.     wcx.hIconSm=NULL;
  156.  
  157.     //register the window class, return 0 if not successful
  158.     if(!RegisterClassEx(&wcx)) return(0);
  159.  
  160.     //create main window
  161.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
  162.  
  163.     //error check
  164.     if(!hWndMain) return(0);
  165.  
  166.     //if program initialization failed, then return with 0
  167.     if(!Prog_Init()) return(0);
  168.  
  169.     //message structure
  170.     MSG msg;
  171.  
  172.     //message pump
  173.     for(;;)    
  174.     {
  175.         //look for a message
  176.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  177.         {
  178.             //there is a message
  179.  
  180.             //check that we arent quitting
  181.             if(msg.message==WM_QUIT) break;
  182.             
  183.             //translate message
  184.             TranslateMessage(&msg);
  185.  
  186.             //dispatch message
  187.             DispatchMessage(&msg);
  188.         }
  189.  
  190.         //run main game loop
  191.         Prog_Loop();
  192.     }
  193.     
  194.     //clean up program data
  195.     Prog_Done();
  196.  
  197.     //return the wparam from the WM_QUIT message
  198.     return(msg.wParam);
  199. }
  200.  
  201. //////////////////////////////////////////////////////////////////////////////
  202. //INITIALIZATION
  203. //////////////////////////////////////////////////////////////////////////////
  204. bool Prog_Init()
  205. {
  206.     //set up ddraw
  207.     lpdd=LPDD_Create(hWndMain,DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
  208.     lpdd->SetDisplayMode(640,480,16,0,0);
  209.  
  210.     //set up primary surface
  211.     lpddsMain=LPDDS_CreatePrimary(lpdd,1);
  212.  
  213.     //set up back buffer
  214.     lpddsBack=LPDDS_GetSecondary(lpddsMain);
  215.  
  216.     //create clipper
  217.     lpdd->CreateClipper(0,&lpddClipper,NULL);
  218.     lpddClipper->SetHWnd(0,hWndMain);
  219.     lpddsBack->SetClipper(lpddClipper);
  220.  
  221.     //load in tileset
  222.     tsIso.Load(lpdd,"IsoHex14_2.bmp");
  223.  
  224.     //set up spaces
  225.     SetUpSpaces();
  226.  
  227.     //set up the tilemap
  228.     SetUpMap();
  229.  
  230.     return(true);//return success
  231. }
  232.  
  233. //////////////////////////////////////////////////////////////////////////////
  234. //CLEANUP
  235. //////////////////////////////////////////////////////////////////////////////
  236. void Prog_Done()
  237. {
  238.     //clean up clipper
  239.     LPDDCLIP_Release(&lpddClipper);
  240.     //clean up primary surface
  241.     LPDDS_Release(&lpddsMain);
  242.     //clean up ddraw
  243.     LPDD_Release(&lpdd);
  244. }
  245.  
  246. //////////////////////////////////////////////////////////////////////////////
  247. //MAIN GAME LOOP
  248. //////////////////////////////////////////////////////////////////////////////
  249. void Prog_Loop()
  250. {
  251.     //check for keys, and adjust screen anchor
  252.     //up
  253.     if(GetAsyncKeyState(VK_UP)<0)
  254.     {
  255.         if(ptScreenAnchor.y>rcAnchorSpace.top) ptScreenAnchor.y--;
  256.     }
  257.     //down
  258.     if(GetAsyncKeyState(VK_DOWN)<0)
  259.     {
  260.         if(ptScreenAnchor.y<rcAnchorSpace.bottom) ptScreenAnchor.y++;
  261.     }
  262.     //right
  263.     if(GetAsyncKeyState(VK_RIGHT)<0)
  264.     {
  265.         if(ptScreenAnchor.x<rcAnchorSpace.right) ptScreenAnchor.x++;
  266.     }
  267.     //left
  268.     if(GetAsyncKeyState(VK_LEFT)<0)
  269.     {
  270.         if(ptScreenAnchor.x>rcAnchorSpace.left) ptScreenAnchor.x--;
  271.     }
  272.  
  273.     //clear out back buffer
  274.     DDBLTFX ddbltfx;
  275.     DDBLTFX_ColorFill(&ddbltfx,0);
  276.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  277.  
  278.     //show the board
  279.     DrawMap();
  280.     //flip
  281.     lpddsMain->Flip(NULL,DDFLIP_WAIT);
  282. }
  283.  
  284. POINT DiamondMap_TilePlotter(POINT ptMap,int iTileWidth,int iTileHeight)
  285. {
  286.     POINT ptReturn;
  287.     //calculate pixel position for the map position given
  288.     ptReturn.x=(ptMap.x-ptMap.y)*iTileWidth/2;
  289.     ptReturn.y=(ptMap.x+ptMap.y)*iTileHeight/2;
  290.     //return calculate point
  291.     return(ptReturn);
  292. }
  293.  
  294. void SetUpMap()
  295. {
  296.     //randomly set up the map
  297.     for(int x=0;x<MAPWIDTH;x++)
  298.     {
  299.         for(int y=0;y<MAPHEIGHT;y++)
  300.         {
  301.             iTileMap[x][y]=rand()%(tsIso.GetTileCount());
  302.         }
  303.     }
  304. }
  305.  
  306. void DrawMap()
  307. {
  308.     POINT ptTile;//tile pixel coordinate
  309.     POINT ptMap;//map coordinate
  310.     //get tile width and height
  311.     int iTileWidth=tsIso.GetTileList()[0].rcSrc.right-tsIso.GetTileList()[0].rcSrc.left;
  312.     int iTileHeight=tsIso.GetTileList()[0].rcSrc.bottom-tsIso.GetTileList()[0].rcSrc.top;
  313.     //the y loop is outside, because we must blit in horizontal rows
  314.     for(int y=0;y<MAPHEIGHT;y++)
  315.     {
  316.         for(int x=0;x<MAPWIDTH;x++)
  317.         {
  318.             //get pixel coordinate for map position
  319.             ptMap.x=x;
  320.             ptMap.y=y;
  321.             ptTile=DiamondMap_TilePlotter(ptMap,iTileWidth,iTileHeight);
  322.             //plot the tile(adjust for anchor)
  323.             tsIso.PutTile(lpddsBack,ptTile.x-ptScreenAnchor.x,ptTile.y-ptScreenAnchor.y,iTileMap[x][y]);
  324.         }
  325.     }
  326. }
  327.  
  328. void SetUpSpaces()
  329. {
  330.     //set up screen space
  331.     SetRect(&rcScreenSpace,0,0,640,480);
  332.     
  333.     //get a few metrics from the tileset
  334.     int iTileWidth=tsIso.GetTileList()[0].rcDstExt.right-tsIso.GetTileList()[0].rcDstExt.left;
  335.     int iTileHeight=tsIso.GetTileList()[0].rcDstExt.bottom-tsIso.GetTileList()[0].rcDstExt.top;
  336.  
  337.     //grab tile rectangle from tileset
  338.     RECT rcTile1;
  339.     RECT rcTile2;
  340.     RECT rcTile3;
  341.     RECT rcTile4;
  342.     RECT rcWS1;
  343.     RECT rcWS2;
  344.     POINT ptPlot;
  345.     POINT ptMap;
  346.  
  347.     //grab tiles from extents
  348.     CopyRect(&rcTile1,&tsIso.GetTileList()[0].rcDstExt);
  349.     CopyRect(&rcTile2,&tsIso.GetTileList()[0].rcDstExt);
  350.     CopyRect(&rcTile3,&tsIso.GetTileList()[0].rcDstExt);
  351.     CopyRect(&rcTile4,&tsIso.GetTileList()[0].rcDstExt);
  352.  
  353.     //move first tile to top position
  354.     ptMap.x=0;
  355.     ptMap.y=0;
  356.     ptPlot=DiamondMap_TilePlotter(ptMap,iTileWidth,iTileHeight);
  357.     OffsetRect(&rcTile3,ptPlot.x,ptPlot.y);
  358.  
  359.     //move first tile to bottom position
  360.     ptMap.x=MAPWIDTH-1;
  361.     ptMap.y=MAPHEIGHT-1;
  362.     ptPlot=DiamondMap_TilePlotter(ptMap,iTileWidth,iTileHeight);
  363.     OffsetRect(&rcTile2,ptPlot.x,ptPlot.y);
  364.  
  365.     //move first tile to left position
  366.     ptMap.x=0;
  367.     ptMap.y=MAPHEIGHT-1;
  368.     ptPlot=DiamondMap_TilePlotter(ptMap,iTileWidth,iTileHeight);
  369.     OffsetRect(&rcTile4,ptPlot.x,ptPlot.y);
  370.  
  371.     //move first tile to right position
  372.     ptMap.x=MAPWIDTH-1;
  373.     ptMap.y=0;
  374.     ptPlot=DiamondMap_TilePlotter(ptMap,iTileWidth,iTileHeight);
  375.     OffsetRect(&rcTile3,ptPlot.x,ptPlot.y);
  376.  
  377.     //combine these four tiles into world space
  378.     UnionRect(&rcWS1,&rcTile1,&rcTile2);
  379.     UnionRect(&rcWS2,&rcTile3,&rcTile4);
  380.     UnionRect(&rcWorldSpace,&rcWS1,&rcWS2);
  381.  
  382.     //copy worldspace to anchor space
  383.     CopyRect(&rcAnchorSpace,&rcWorldSpace);
  384.  
  385.     //subtract out screenspace
  386.     //adjust right edge
  387.     rcAnchorSpace.right-=(rcScreenSpace.right-rcScreenSpace.left);
  388.     //make sure right not less than left
  389.     if(rcAnchorSpace.right<rcAnchorSpace.left) rcAnchorSpace.right=rcAnchorSpace.left;
  390.     //adjust bottom edge
  391.     rcAnchorSpace.bottom-=(rcScreenSpace.bottom-rcScreenSpace.top);
  392.     //make sure bottom not less than top
  393.     if(rcAnchorSpace.bottom<rcAnchorSpace.top) rcAnchorSpace.bottom=rcAnchorSpace.top;
  394.  
  395.     //initialize screen anchor
  396.     ptScreenAnchor.x=0;
  397.     ptScreenAnchor.y=0;
  398. }
  399.